import { _decorator, Component, Node, input, Input, EventKeyboard, KeyCode } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('CarCtrl')
export class CarCtrl extends Component {
  // Movement properties
  @property(Number)
  public moveSpeed: number = 5;

  // Boundary properties
  @property(Number)
  public leftBoundary: number = -8;

  @property(Number)
  public rightBoundary: number = 8;

  // State properties
  @property(Boolean)
  public isMoving: boolean = false;

  @property(Boolean)
  public raceFinished: boolean = false;

  // Camera properties
  @property(Node)
  public camera: Node = null;

  // Camera's z offset from the car
  public cameraZOffset: number = 10;

  // Movement direction tracking
  private moveDirection: number = 0; // -1 for left, 0 for straight, 1 for right
  private pressedKeys: Set<KeyCode> = new Set();

  onLoad() {
    console.log('CarCtrl onLoad');
    // Register keyboard event listeners
    input.on(Input.EventType.KEY_DOWN, this.onKeyDown, this);
    input.on(Input.EventType.KEY_UP, this.onKeyUp, this);

    // setTimeout(() => {
    //     this.node.active = false;
    // }, 5_000);

    // Initialize camera position
    if (this.camera) {
      this.cameraZOffset = this.camera.position.z - this.node.position.z;
    }
  }

  onDestroy() {
    console.log('CarCtrl onDestroy');

    // Remove keyboard event listeners
    input.off(Input.EventType.KEY_DOWN, this.onKeyDown, this);
    input.off(Input.EventType.KEY_UP, this.onKeyUp, this);
  }

  start() {
    console.log('CarCtrl start');
  }

  update(deltaTime: number) {
    // Don't move if race is finished
    if (this.raceFinished) {
      return;
    }

    // Move the car forward along the Z axis at a constant speed
    // Also move left/right based on input
    const forwardMovement = -this.moveSpeed * deltaTime;
    const sideMovement = this.moveDirection * this.moveSpeed * deltaTime;

    // Calculate new position
    const newPosition = this.node.position.add3f(sideMovement, 0, forwardMovement);

    // Apply boundary constraints to X position
    const clampedX = Math.max(this.leftBoundary, Math.min(this.rightBoundary, newPosition.x));

    // Set position with boundary constraints
    this.node.position = newPosition.clone().set(clampedX, newPosition.y, newPosition.z);

    // Update camera position aligned with the car
    if (this.camera) {
      this.camera.setPosition(
        this.camera.position.x,
        this.camera.position.y,
        this.node.position.z + this.cameraZOffset
      );
    }

    // Update isMoving state
    this.isMoving = this.moveDirection !== 0 || this.moveSpeed > 0;
  }

  lateUpdate(deltaTime: number) {
    // console.log('CarCtrl lateUpdate');
  }

  onEnable() {
    console.log('CarCtrl onEnable');
  }

  onDisable() {
    console.log('CarCtrl onDisable');
  }

  // Keyboard event handlers
  private onKeyDown(event: EventKeyboard) {
    this.pressedKeys.add(event.keyCode);
    this.updateMovementDirection();
  }

  private onKeyUp(event: EventKeyboard) {
    this.pressedKeys.delete(event.keyCode);
    this.updateMovementDirection();
  }

  private updateMovementDirection() {
    let direction = 0;

    // Check for left movement (A key or Left Arrow)
    if (this.pressedKeys.has(KeyCode.KEY_A) || this.pressedKeys.has(KeyCode.ARROW_LEFT)) {
      direction -= 1;
    }

    // Check for right movement (D key or Right Arrow)
    if (this.pressedKeys.has(KeyCode.KEY_D) || this.pressedKeys.has(KeyCode.ARROW_RIGHT)) {
      direction += 1;
    }

    this.moveDirection = direction;
  }

  // Race completion handler
  public onRaceFinished() {
    console.log('Race completed! Stopping car movement.');
    this.raceFinished = true;
    this.isMoving = false;

    // You can add additional race completion logic here:
    // - Show finish time
    // - Display victory message
    // - Play celebration effects
    // - Reset for next race
  }

  // Method to reset race state
  public resetRace() {
    this.raceFinished = false;
    this.isMoving = false;
    this.moveDirection = 0;
    this.pressedKeys.clear();
  }
}
